<template>
  <div class="tab">
    <cube-tab-bar
      ref="tabBar"
      v-model="selectedLabel"
      :data="tabs"
      :useTransition="false"
      show-slider
    >
    </cube-tab-bar>
    <div class="slide-wrapper">
      <cube-slide
        ref="slide"
        :loop="false"
        :auto-play="false"
        :show-dots="false"
        :initial-index="index"
        :options="slideOptions"
        @change="onChange"
        @scroll="onScroll"
      >
        <cube-slide-item v-for="(item, index) in tabs" :key="index">
          <component :is="item.component" :data="item.data" ref="component" />
        </cube-slide-item>
      </cube-slide>
    </div>
  </div>
</template>
<script>
export default {
  name: "Tab",
  props: {
    tabs: Array,
    // 如果像进入页面显示想要的子页面，可以通过父组件传递该值
    initialIndex: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      index: this.initialIndex,
      // better-scroll 的配置
      slideOptions: {
        // 滚动时派发 scroll 事件
        listenScroll: true,
        // 有时候我们需要知道滚动的位置。默认值为 0，可选值为 1，2，3
        // 当 probeType 为 1 的时候，会非实时（屏幕滑动超过一定时间后）派发scroll 事件；
        // 当 probeType 为 2 的时候，会在屏幕滑动的过程中实时的派发 scroll 事件；
        // 当 probeType 为 3 的时候，不仅在屏幕滑动的过程中，而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。
        // 如果没有设置该值，其默认值为 0，即不派发 scroll 事件。
        probeType: 3,
        // 当我们需要锁定只滚动一个方向的时候，我们在初始滚动的时候根据横轴和纵轴滚动的绝对值做差，当差值大于 directionLockThreshold 的时候来决定滚动锁定的方向。
        // 默认值为 5，避免出现斜着滚动的情况
        directionLockThreshold: 0,
      },
    };
  },
  computed: {
    selectedLabel: {
      get() {
        // console.log(this.tabs[this.index].label);
        return this.tabs[this.index].label;
      },
      set(newValue) {
        this.index = this.tabs.findIndex((value) => {
          // console.log(value, newValue);
          return value.label === newValue;
        });
      },
    },
  },
  methods: {
    onChange(current) {
      this.index = current;
      const component = this.$refs.component[current];
      component.fetch && component.fetch();
    },
    // 监听 slide 滑动，在 slide 滑动时，下划线也应该滑动对应的位置
    onScroll(position) {
      // console.log(position.x, this.$refs.tabBar, this.$refs.slide);
      // 1. 获取 tabBar 的宽度
      const tabBarWidth = this.$refs.tabBar.$el.clientWidth;
      // 2. 获取 slide 的宽度
      const slideWidth = this.$refs.slide.slide.scrollerWidth;
      // 3. 下划线要变化的宽度
      // 往右移 position.x 为负数，position / slideWidth 得到的是 slide 当前滑动的位置，再乘以 tabBarWidth 就可以得到滑动时下划线的位置
      const transform = (-position.x / slideWidth) * tabBarWidth;
      // 4. 通过 setSliderTransform 改变 tabBar组件的下划线的 transformX，可以传数值，也可以传带单位的 String
      this.$refs.tabBar.setSliderTransform(transform);
    },
  },
  mounted() {
    this.onChange(this.index);
    // console.log(this.tabs);
  },
};
</script>
<style lang="stylus" scoped>
.tab
  display flex
  flex-direction column
  height 100%
  >>> .cube-tab
    padding 10px 0
  .slide-wrapper
    flex 1
    overflow hidden
</style>